#ifndef DataHolder_H_
#define DataHolder_H_

#include <string.h>
#include <stdint.h>

#pragma pack(push)
#pragma pack(1)

struct Robot_firmware
{
    char version[16]; //固件版本
    char time[16];    //构建时间
};

struct Robot_parameter
{
    union
    {
        char buff[64];
        struct
        {
            unsigned short wheel_diameter;     //轮子直径  mm
            unsigned short wheel_track;        //差分：轮距， 三全向轮：直径，四全向：前后轮距+左右轮距 mm
            unsigned short encoder_resolution; //编码器分辨率
            unsigned char do_pid_interval;     //pid间隔 (ms)
            unsigned short kp;
            unsigned short ki;
            unsigned short kd;
            unsigned short ko;            //pid参数比例
            unsigned short cmd_last_time; //命令持久时间ms 超过该时间会自动停止运动
            unsigned short max_v_liner_x;
            unsigned short max_v_liner_y;
            unsigned short max_v_angular_z;
            unsigned char imu_type;
        };
    };
};

struct Robot_velocity
{
    short v_liner_x;   //线速度 前>0 mm/s
    short v_liner_y;   //差分轮 为0  mm/s
    short v_angular_z; //角速度 左>0 0.01rad/s  100 means 1 rad/s
};

struct Robot_odom
{
    short v_liner_x;   //线速度 前>0 后<0  cm/s
    short v_liner_y;   //差分轮 为0        cm/s
    short v_angular_z; //角速度 左>0 右<0  0.01rad/s   100 means 1 rad/s
    int32_t x;           //里程计坐标x       cm (这里long为4字节，下同)
    int32_t y;           //里程计坐标y       cm
    short yaw;         //里程计航角        0.01rad     100 means 1 rad
};

struct Robot_each_motor
{
    short vL; //左电机
    short vR; //右电机
};

typedef struct _RobotState{
    
    struct wheel_state{
        uint8_t ready;               //两个驱动是否OK
        double actual_rpm;           //实际转速
        double turns;                //电机圈数
        double odom;
    };
    
    struct encoder_state{
        uint8_t ready;
        double  turns;                //圈数
        double  odom;                 //用外置编码器算得的里程
    };
    
    struct wheel_state wheels[2];
    struct encoder_state encoder;

}RobotState_T;

/* 设置odom的偏移量，修正odom偏差 */
typedef struct _OdomTf
{
    float dx;
    float dy;
    float dth;
} OdomTf_T;

#pragma pack(pop)

typedef struct _MsgFlag
{
    bool version;
    bool odom;
    bool robot_state;
} MsgFlag_T;

class DataHolder
{
public:
    static DataHolder *get()
    {
        static DataHolder dh;
        return &dh;
    }

    void load_parameter();
    void save_parameter();

private:
    DataHolder()
    {
        memset(&firmware_info, 0, sizeof(struct Robot_firmware));
        memset(&parameter, 0, sizeof(struct Robot_parameter));
        memset(&velocity, 0, sizeof(struct Robot_velocity));
        memset(&odom, 0, sizeof(struct Robot_odom));
        memset(&each_motor, 0, sizeof(each_motor));
        memset(&robot_state, 0, sizeof(robot_state));
        memset(&odom_tf, 0, sizeof(odom_tf));
    }

public:
    MsgFlag_T msg_flags;

public:
    bool power_onoff;
    struct Robot_firmware firmware_info;
    struct Robot_parameter parameter;
    struct Robot_velocity velocity;
    struct Robot_odom odom;
    struct Robot_each_motor each_motor;
    RobotState_T robot_state;
    OdomTf_T odom_tf;

};
#endif